// ReSharper disable InconsistentNaming

using System.Configuration;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;

namespace InsideSalesApiClient
{
    public class InsideSalesApiService : IInsideSalesApiService
    {
        #region private members and ctor

        private readonly CookieContainer _cookieJar;

        /// <summary>
        /// Posts the request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="requestBody">The request body.</param>
        /// <returns></returns>
        private string PostRequest(HttpWebRequest request, string requestBody)
        {
            request.CookieContainer = _cookieJar;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            var byteData = Encoding.UTF8.GetBytes(requestBody);
            request.ContentLength = byteData.Length;

            using (var postStream = request.GetRequestStream())
            {
                postStream.Write(byteData, 0, byteData.Length);
            }

            using (var response = request.GetResponse() as HttpWebResponse)
            {
                if (response != null)
                {
                    var responseStream = response.GetResponseStream();
                    if (responseStream != null)
                    {
                        var reader = new StreamReader(responseStream);
                        var readerContent = reader.ReadToEnd();
                        return readerContent;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InsideSalesApiService"/> class.
        /// </summary>
        public InsideSalesApiService()
        {
            var userName = ConfigurationManager.AppSettings.Get("InsideSalesUsername");
            if (string.IsNullOrEmpty(userName))
                throw new ConfigurationErrorsException("Expected configuration value: InsideSalesUsername");

            var password = ConfigurationManager.AppSettings.Get("InsideSalesPassword");
            if (string.IsNullOrEmpty(password))
                throw new ConfigurationErrorsException("Expected configuration value: InsideSalesPassword");

            var token = ConfigurationManager.AppSettings.Get("InsideSalesToken");
            if (string.IsNullOrEmpty(token))
                throw new ConfigurationErrorsException("Expected configuration value: InsideSalesToken");

            var webserviceUrl = ConfigurationManager.AppSettings.Get("InsideSalesWebServiceUrl");
            if (string.IsNullOrEmpty(webserviceUrl))
                throw new ConfigurationErrorsException("Expected configuration value: Web Service Url");
            WebServiceUrl = webserviceUrl;

            _cookieJar = new CookieContainer();

            IsAuthenticated = false;
            var loginParameters = new object[] { userName, password, token };
            var insideSalesLoginRequestBody = new InsideSalesRequestBody
                                                  {
                                                      operation = InsideSalesOperations.Login,
                                                      parameters = loginParameters
                                                  };

            var serializer = new JavaScriptSerializer();
            var requestBody = serializer.Serialize(insideSalesLoginRequestBody);

            var request = WebRequest.Create(WebServiceUrl) as HttpWebRequest;
            if (request == null) 
                return;

            var readerContent = PostRequest(request, requestBody);
            if (readerContent == "true")
                IsAuthenticated = true;
        }

        #endregion

        #region properties

        /// <summary>
        /// Gets or sets the base URL for the CareHQ API.
        /// </summary>
        /// <value>
        /// The store URL.
        /// </value>
        public string WebServiceUrl { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is authenticated.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is authenticated; otherwise, <c>false</c>.
        /// </value>
        public bool IsAuthenticated { get; set; }

        #endregion

        /// <summary>
        /// Adds the lead.
        /// </summary>
        /// <param name="lead">The lead.</param>
        /// <param name="addLeadOptions">The inside sales add lead options.</param>
        /// <returns></returns>
        public int AddLead(InsideSalesLead lead, InsideSalesAddLeadOptions addLeadOptions)
        {
            var insideSalesAddLeadRequestBody = new InsideSalesRequestBody
                                                    {
                                                        operation = InsideSalesOperations.AddLead,
                                                        parameters = new object[] {lead, addLeadOptions}
                                                    };

            var serializer = new JavaScriptSerializer();
            var requestBody = serializer.Serialize(insideSalesAddLeadRequestBody);

            var newLeadId = 0;

            var request = WebRequest.Create(WebServiceUrl) as HttpWebRequest;
            if (request != null)
            {
                var readerContent = PostRequest(request, requestBody);
                newLeadId = serializer.Deserialize<int>(readerContent);
            }

            return newLeadId;
        }

        /// <summary>
        /// Available Operations
        /// </summary>
        public static class InsideSalesOperations
        {
            public static string Login
            {
                get { return "login"; }
            }

            public static string AddLead
            {
                get { return "addLead"; }
            }
        }
    }
}